package com.mobilevikings.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Hashtable;

public class Properties {

    public Properties() {
        mData = new Hashtable();
    }

    public boolean read(String inResourceName) throws NullPointerException, UnsupportedEncodingException, IOException {
        return read(Properties.class.getResourceAsStream(inResourceName));
    }

    public boolean read(InputStream inStream) throws NullPointerException, UnsupportedEncodingException, IOException {
        InputStreamReader reader = new InputStreamReader(inStream, "UTF-8");

        StringBuffer keyBuffer = null;
        StringBuffer valueBuffer = null;

        int state = kStateStart;

        int c = reader.read();
        while (c >= 0) {
            switch (state) {
                case kStateStart: {
                    switch (c) {
                        case ' ':
                        case '\t':
                        case '\n':
                        case '\r': {
                            state = kStateStart;
                            break;
                        }
                        default: {
                            state = kStateKey;
                            keyBuffer = new StringBuffer();
                            keyBuffer.append((char) c);
                            break;
                        }
                    }
                    break;
                }
                case kStateKey: {
                    switch (c) {
                        case '=': {
                            state = kStateEquals;
                            break;
                        }
                        case '\r':
                        case '\n': {
                            state = kStateStart;
                            break;
                        }
                        default: {
                            keyBuffer.append((char) c);
                            break;
                        }
                    }
                    break;
                }
                case kStateEquals: {
                    switch (c) {
                        case '\r':
                        case '\n': {
                            state = kStateStart;
                            break;
                        }
                        default: {
                            state = kStateValue;
                            valueBuffer = new StringBuffer();
                            valueBuffer.append((char) c);
                            break;
                        }
                    }
                    break;
                }
                case kStateValue: {
                    switch (c) {
                        case '\r':
                        case '\n': {
                            set(keyBuffer.toString().trim(), valueBuffer.toString().trim());
                            keyBuffer = null;
                            valueBuffer = null;

                            state = kStateStart;
                            break;
                        }
                        default: {
                            valueBuffer.append((char) c);
                            break;
                        }
                    }
                    break;
                }
            }

            c = reader.read();
        }

        if (keyBuffer != null && valueBuffer != null) {
            set(keyBuffer.toString().trim(), valueBuffer.toString().trim());
        }

        return true;

    }

    public void set(String inKey, String inValue) {
        mData.put(inKey, inValue);
    }

    public String get(String inKey) {
        return get(inKey, inKey);
    }

    public String get(String inKey, String inDefaultValue) {
        String result = (String) mData.get(inKey);
        return result == null ? inDefaultValue : result;
    }
    private Hashtable mData;
    private static final int kStateStart = 0;
    private static final int kStateKey = 1;
    private static final int kStateEquals = 2;
    private static final int kStateValue = 3;
}